(function($) {
	
	$.fn.ssAutoComplete = function(obj) {
		var html = "<div class=\"row\">" +
							"<span class='desc'>:desc</span>" +
							"<h1>:header</h1>" +
					"</div>";
		this.each(function(index) {
			var mouse_inside_autocomplete_span = false;
			var Self = {
				object : $(this),
				Input : $(this).find('.get input[type=text]'),
				Output : $(this).find('.result'),
				Message : $(this).find('.message'),
				messageText : Util.isEmpty(obj.message) ? null : obj.message
			};
			
			Self.Message.hide();
			
			Self.Output
				.mouseover(function() {
					mouse_inside_autocomplete_span = true;
				})
				.mouseout(function() {
					mouse_inside_autocomplete_span = false;
				})
				.hide();
			
			Self.Input
				.click(function(event) {
					if(Util.isEmpty( Util.trim( Self.Input.val() ) )) {
						if( Util.isFunction( obj.onClick ) ) {
							obj.onClick(Self, event);
						}
						if (!Util.isEmpty(Self.messageText)) {
							Self.Message.show().find('.inner').html(Self.messageText);
						}
						else {
							Self.Message.hide();
						}
					}
				})
				.mouseover(function() {
					mouse_inside_autocomplete_span = true;
				})
				.mouseout(function() {
					mouse_inside_autocomplete_span = false;
				})
				.keyup(function(event) {
					var code = (event.keyCode ? event.keyCode : event.which);
					if ((code == 13 && !event.shiftKey) || code == 38 || code == 40) {
						event.preventDefault();
					}
					else {
						var key = Util.strtolower( Util.trim( Self.Input.val() ) );
						if( !Util.isEmpty(key) ) {
							Self.Message.hide();
							Self.messageText = null;
							if( Util.isFunction( obj.onClick ) ) {
								obj.onType(Self, event, key, html, function(data) {
									if(Self.Output.is(':visible')) {
										Self.Output.find('div.row')
											.hover(function() {
													ssAutoComplete.highlight(Self, $(this), null, obj);
											})
											.click(function(event) {
												var Row = $(this);
												ssAutoComplete.select(Self, Row, event, obj, data, Row.index());
											})
											.first().addClass('select');
										
										$('body').unbind('keypress').keypress(function(event) {
											var code = (event.keyCode ? event.keyCode : event.which);
											if (code == 13 && !event.shiftKey && Self.Output.is(':visible')) {
												var Row = Self.Output.find('.select');
												ssAutoComplete.select(Self, Row, event, obj, data, Row.index());
												event.preventDefault();
											}
											else if(code == 38 && Self.Output.is(':visible')) {
												//up arraow
												var Row = Self.Output.find('.select').prev();
												if(Row.is(':first'))
													Row = Self.Output.find('.row').last();
												ssAutoComplete.highlight(Self, Row, null, obj);
												event.preventDefault();
											}
											else if(code == 40 && Self.Output.is(':visible')) {
												//down arraow
												var Row = Self.Output.find('.select').next();
												if(Row.is(':last'))
													Row = Self.Output.find('.row').first();
												ssAutoComplete.highlight(Self, Row, null, obj);
												event.preventDefault();
											}
										});
									}
									else {
										if (!Util.isEmpty(Self.messageText)) {
											Self.Message.show().find('.inner').html(Self.messageText);
										}
									}
								});
							}
						}
						else {
							if( Util.isFunction( obj.onEmpty ) ) {
								Self.Output.hide().html('');
								obj.onEmpty(Self, event);
								if (!Util.isEmpty(Self.messageText)) {
									Self.Message.show().find('.inner').html(Self.messageText);
								}
								else {
									Self.Message.hide();
								}
							}
						}
					}
				});
			
			$('body').click(function(event) {
				if(!mouse_inside_autocomplete_span && Self.Message.is(':visible')) {
					Self.Message.hide();
				}
				if(!mouse_inside_autocomplete_span && Self.Output.is(':visible')) {
					Self.Output.hide();
					if( Util.isFunction( obj.onClick ) ) {
						obj.onDestroy(Self, event);
					}
				}
			});
		});
	};
	
})(jQuery);

var ssAutoComplete = {
	select : function(Self, Row, event, obj, data, index) {
		var value = Util.stripHTML( Row.find('h1').html() );
		Self.Input.val(value);
		Self.Output.html('').hide();
		if( Util.isFunction( obj.onSelect ) ) {
			obj.onSelect(Self, event, Row, data[index]);
			if (!Util.isEmpty(Self.messageText)) {
				Self.Message.show().find('.inner').html(Self.messageText);
			}
			else {
				Self.Message.hide();
			}
		}
	},
	
	highlight : function(Self, Row, event, obj) {
		Self.Output.find('div.row').not(Row).removeClass('select');
		Row.addClass('select');
	}
}